package ldh.im.fxgui.controller.sub;

import com.jfoenix.controls.JFXDialog;
import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.property.BooleanProperty;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;
import ldh.im.ImConfig;
import ldh.im.dto.business.base.DataChangeReq;
import ldh.im.dto.enums.DataSubType;
import ldh.im.dto.enums.DataType;
import ldh.im.fxbase.dao.ImGroupDao;
import ldh.im.fxbase.dao.ImGroupUserDao;
import ldh.im.fxbase.data.event.EventBusFactory;
import ldh.im.fxbase.data.event.GroupNameChange;
import ldh.im.fxbase.data.event.GroupUserNameChange;
import ldh.im.fxbase.data.pojo.ImGroupUser;
import ldh.im.fxbase.data.pojo.ImSession;
import ldh.im.fxbase.data.pojo.ImUser;
import ldh.im.fxbase.rpc.service.RpcMessageService;
import ldh.im.fxbase.service.MessageService;
import ldh.im.fxbase.util.*;
import ldh.im.fxgui.controller.IndependentController;
import ldh.im.fxgui.handle.IGroupControl;
import ldh.im.fxgui.util.UiUtil;
import ldh.im.fxgui.util.UserHeadImageUtil;

import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.ResourceBundle;
import java.util.stream.Collectors;

/**
 * 消息-》会话(p2g)-》消息栏-》设置
 * 从群消息处，邀请用户进群
 */
public class SessionGroupSettingController extends IndependentController implements IGroupControl, Initializable {

    private static final int SHOW_MAX_USER_LIMIT = 12;

//    @FXML private ImageView ownerHeadImageView;
    @FXML private Pane userFowPane;
    @FXML private Button moreUserBtn;
    @FXML private TextField searchTextField;
    @FXML private TextField groupNameTextField;
    @FXML private TextField userNameTextField;
    @FXML private TextArea groupDescTextArea;

    private BooleanProperty settingPaneShowProperty;

    private ImSession currentImSession;

    private ImGroupDao imGroupDao = BeanFactory.getInstance().getBean(ImGroupDao.class);
    private ImGroupUserDao imGroupUserDao = BeanFactory.getInstance().getBean(ImGroupUserDao.class);
    private RpcMessageService rpcMessageService = RpcUtil.getRpcBootstrap().getRpcConfig().getClientBean(RpcMessageService.class);

    public void setParams(ImSession imSession, BooleanProperty settingPaneShowProperty) {
        this.currentImSession = imSession;
        this.settingPaneShowProperty = settingPaneShowProperty;

        List<Node> userPanes = imSession.getImGroup().getGroupUserSet().stream().limit(SHOW_MAX_USER_LIMIT).map(u->userInfoBox(u)).collect(Collectors.toList());
        userFowPane.getChildren().addAll(userPanes);

        if(imSession.getImGroup().getGroupUserSet().size() > SHOW_MAX_USER_LIMIT) {
            moreUserBtn.setDisable(false);
        } else {
            moreUserBtn.setDisable(true);
        }

        groupNameTextField.setText(imSession.getImGroup().getName());

        String userName = UiUtil.getLoginImUser().getUserName();
        ImGroupUser imGroupUser = imSession.getImGroup().getGroupUserSet().stream().filter(gu->gu.getUserId().equals(UiUtil.getLoginImUser().getUserId())).findFirst().get();
        userName = imGroupUser.getUserName() != null ? imGroupUser.getUserName() : userName;
        userNameTextField.setText(userName);

        groupDescTextArea.setText(imSession.getImGroup().getDescription());
    }

    @Override
    public void refresh() {
        userFowPane.getChildren().clear();
        List<Node> userPanes = currentImSession.getImGroup().getGroupUserSet().stream().limit(SHOW_MAX_USER_LIMIT).map(u->userInfoBox(u)).collect(Collectors.toList());
        userFowPane.getChildren().addAll(userPanes);

        if(currentImSession.getImGroup().getGroupUserSet().size() > SHOW_MAX_USER_LIMIT) {
            moreUserBtn.setDisable(false);
        } else {
            moreUserBtn.setDisable(true);
        }
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {
        searchTextField.textProperty().addListener((InvalidationListener) l->{
            filterUsers();
        });

//        groupDescTextArea.focusedProperty().addListener(l->{
//            if (!groupDescTextArea.isFocused()) {
//                saveGroupDescription();
//            }
//        });
    }

    @FXML
    private void showAddUserPane(ActionEvent actionEvent) {
        RegionUtil.FxmlBean<Pane, AddUserToGroupController> fxmlBean = RegionUtil.loadFxmlBean(this.getClass().getResource("/fxml/sub/AddUserToGroupPane.fxml"));
        JFXDialog dialog = DialogUtil.show(fxmlBean.getNode(), false);
        dialog.setPrefSize(600, 400);
        fxmlBean.getController().setDialog(dialog);
        fxmlBean.getController().setCurrentImSession(currentImSession);
        fxmlBean.getController().setIGroupControl(this);
        fxmlBean.getController().setSettingPaneShowProperty(settingPaneShowProperty);
    }

    @FXML
    private void showMoreUser(ActionEvent actionEvent) {
        if(moreUserBtn.isDisabled()) return;
        Object userData = moreUserBtn.getUserData();
        if (userData == null || userData.toString().equals("showMoreUser")) {
            List<Node> userPanes = currentImSession.getImGroup().getGroupUserSet().stream().skip(SHOW_MAX_USER_LIMIT).map(u->userInfoBox(u)).collect(Collectors.toList());
            userFowPane.getChildren().addAll(userPanes);
            moreUserBtn.setUserData("foldUpUser");
            moreUserBtn.setText("收起");
            filterUsers();
        } else {
            int size = userFowPane.getChildren().size();
            userFowPane.getChildren().remove(SHOW_MAX_USER_LIMIT, size);
            moreUserBtn.setText("查看更多");
            moreUserBtn.setUserData("showMoreUser");
            filterUsers();
        }
    }

    private Node userInfoBox(ImGroupUser groupUser) {
        String userId = groupUser.getUserId();
        ImUser imUser = ImCacheFactory.getInstance().getUser(userId);
        groupUser.setUser(imUser);
        ImageView imageView = new ImageView(UserHeadImageUtil.getHeadImage(imUser.getHeadImg()));
        imageView.setFitWidth(50);
        imageView.setFitHeight(50);
        String userName = groupUser.getUserName();
        if (userName == null) userName = imUser.getUserName();
        Label label = new Label(userName);
        label.setFont(Font.font(10));
        label.setTooltip(new Tooltip(userName));
        label.setGraphic(imageView);
        label.setContentDisplay(ContentDisplay.TOP);
        label.setUserData(imUser);
        label.setMaxWidth(50);
        return label;
    }

    private void filterUsers() {
        String filter = searchTextField.getText().trim();
        userFowPane.getChildren().forEach(pane->{
            ImUser imUser = (ImUser) pane.getUserData();
            boolean isContain = imUser.getUserName().contains(filter);
            if (!isContain) {
                pane.setVisible(false);
                pane.setManaged(false);
            } else {
                pane.setVisible(true);
                pane.setManaged(true);
            }
        });
    }

    @FXML
    private void saveGroupNameAct(KeyEvent keyEvent) {
        if (keyEvent.getCode() != KeyCode.ENTER) return;
        String value = groupNameTextField.getText().trim();
        if (StringUtil.isEmpty(value)) {
            DialogUtil.alert("提醒", "群名称不能为空");
            return;
        }
        if (StringUtil.isEmpty(currentImSession.getImGroup().getServerId())) {
            DialogUtil.alert("错误", "群serverId不能为空");
            return;
        }
        DataChangeReq dataChangeReq = new DataChangeReq();
        dataChangeReq.setValue(value);
        dataChangeReq.setType(DataType.group);
        dataChangeReq.setSubType(DataSubType.g_ed_name);
        dataChangeReq.setKey(currentImSession.getImGroup().getServerId());
        ThreadPoolUtil.submit(()->{
            ExceptionUtil.catchException(()->{
                rpcMessageService.sendDataChange(dataChangeReq);
                EventBusFactory.getInstance().post(new GroupNameChange(currentImSession.getGroupCode(), value));
                currentImSession.getImGroup().setName(value);
                imGroupDao.update(currentImSession.getImGroup());
                FxThreadUtil.runLater(()->{
                    DialogUtil.showSuccess(getDialogRoot(), "修改群名称成功");
                });
                return null;
            }, e->{
                FxThreadUtil.runLater(()->{
                    DialogUtil.showError(getDialogRoot(), "修改群名称失败");
                });
            }, "修改群名称失败");
        });
    }

    @FXML
    private void saveUserNameAct(KeyEvent keyEvent) {
        if (keyEvent.getCode() != KeyCode.ENTER) return;
        String value = userNameTextField.getText().trim();
        if (StringUtil.isEmpty(value)) {
            DialogUtil.alert("提醒", "用户名称不能为空");
            return;
        }
        if (StringUtil.isEmpty(currentImSession.getImGroup().getServerId())) {
            DialogUtil.alert("错误", "群serverId不能为空");
            return;
        }
        String userId = UiUtil.getLoginImUser().getUserId();
        DataChangeReq dataChangeReq = new DataChangeReq();
        dataChangeReq.setValue(value);
        dataChangeReq.setType(DataType.groupUser);
        dataChangeReq.setSubType(DataSubType.gu_ed_userName);
        dataChangeReq.setKey(currentImSession.getImGroup().getServerId() + ImConfig.MESSAGE_SPLIT + userId);
        ThreadPoolUtil.submit(()->{
            ExceptionUtil.catchException(()->{
                rpcMessageService.sendDataChange(dataChangeReq);
                ImGroupUser groupUser = currentImSession.getImGroup().getGroupUserSet().stream().filter(gu->gu.getUserId().equals(userId)).findFirst().get();
                EventBusFactory.getInstance().post(new GroupUserNameChange(currentImSession.getId(), userId, value));
                groupUser.setUserName(value);
                groupUser.setUpdateTime(new Date());
                imGroupUserDao.update(groupUser);
                FxThreadUtil.runLater(()->{
                    DialogUtil.showSuccess(getDialogRoot(), "修改群用户名成功");
                });
                return null;
            }, e->{
                FxThreadUtil.runLater(()->{
                    DialogUtil.showSuccess(getDialogRoot(), "修改群用户名失败");
                });
            }, "修改群用户名失败");
        });
    }

    @FXML
    private void saveGroupDescAct(KeyEvent keyEvent) {
        if (keyEvent.getCode() != KeyCode.ENTER) return;
        saveGroupDescription();
    }

    @FXML
    public void cleanChatContent(ActionEvent actionEvent) {
        Task<Boolean> cleanTask = new Task() {

            @Override
            protected Object call() throws Exception {
                String userId = UiUtil.getLoginImUser().getUserId();
                MessageService messageService = BeanFactory.getInstance().getBean(MessageService.class);
                messageService.cleanMessage(userId, currentImSession.getId());
                return true;
            }
        };
        ThreadPoolUtil.submitTask(cleanTask);
        cleanTask.setOnSucceeded(s->{
            UiUtil.uiRefresh();
            DialogUtil.showSuccess(getDialogRoot(), "清理成功");
        });
    }

    private void saveGroupDescription() {
        String oldValue = currentImSession.getImGroup().getDescription();
        String value = groupDescTextArea.getText().trim();
        if (value.equals(oldValue)) return;
        if (StringUtil.isEmpty(value)) {
            DialogUtil.alert("提醒", "群介绍不能为空");
            return;
        }
        if (StringUtil.isEmpty(currentImSession.getImGroup().getServerId())) {
            DialogUtil.alert("错误", "群serverId不能为空");
            return;
        }
        if (ObjectUtil.length(value) > 130) {
            DialogUtil.alert("错误", "群介绍太长");
            return;
        }
        DataChangeReq dataChangeReq = new DataChangeReq();
        dataChangeReq.setValue(value);
        dataChangeReq.setType(DataType.group);
        dataChangeReq.setSubType(DataSubType.g_ed_desc);
        dataChangeReq.setKey(currentImSession.getImGroup().getServerId());
        ThreadPoolUtil.submit(()->{
            try {
                rpcMessageService.sendDataChange(dataChangeReq);
                currentImSession.getImGroup().setDescription(value);
                imGroupDao.update(currentImSession.getImGroup());

                FxThreadUtil.runLater(()->{
                    DialogUtil.showSuccess(getDialogRoot(), "修改群介绍成功");
                });

            } catch (Exception e) {
                FxThreadUtil.runLater(()->{
                    DialogUtil.alert("错误", "修改群介绍失败");
                });
            }
        });
    }
}
